「Java SE 7 リリース」 言語拡張メモ
毎度お世話になっております。クラスメソッドの稲毛です。
今回は先日リリースされた「Java SE 7」について、新たに追加された言語拡張についてまとめておきたいと思います。
リファレンスはオラクル社の下記サイトとなります。
http://download.oracle.com/javase/7/docs/technotes/guides/language/enhancements.html#javase7
Javaプログラミング言語の拡張
- Binary Literals
- Underscores in Numeric Literals
- Strings in switch Statements
- Type Inference for Generic Instance Creation
- Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods
- The try-with-resources Statement
- Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking
Binary Literals
バイナリのリテラル表現
バイナリ値の接頭辞に「0b」または「0B」を追加することで、整数型(byte, short, int, long)の値をリテラルで表現できるようになりました。
// An 8-bit 'byte' value: byte aByte = (byte)0b00100001; // A 16-bit 'short' value: short aShort = (short)0b1010000101000101; // Some 32-bit 'int' values: int anInt1 = 0b10100001010001011010000101000101; int anInt2 = 0b101; int anInt3 = 0B101; // The B can be upper or lower case. // A 64-bit 'long' value. Note the "L" suffix: long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;
http://download.oracle.com/javase/7/docs/technotes/guides/language/binary-literals.html
Underscores in Numeric Literals
アンダースコアを含んだ数値リテラル
数値リテラルにアンダースコア「_」を含める事ができるようになりました。数値リテラルの可読性向上等に利用することができます。
long creditCardNumber = 1234_5678_9012_3456L; long socialSecurityNumber = 999_99_9999L; float pi = 3.14_15F; long hexBytes = 0xFF_EC_DE_5E; long hexWords = 0xCAFE_BABE; long maxLong = 0x7fff_ffff_ffff_ffffL; byte nybbles = 0b0010_0101; long bytes = 0b11010010_01101001_10010100_10010010;
ただし、アンダースコアを挿入する位置に注意する必要があります。
float pi1 = 3_.1415F; // Invalid; cannot put underscores adjacent to a decimal point float pi2 = 3._1415F; // Invalid; cannot put underscores adjacent to a decimal point long socialSecurityNumber1 = 999_99_9999_L; // Invalid; cannot put underscores prior to an L suffix int x1 = _52; // This is an identifier, not a numeric literal int x2 = 5_2; // OK (decimal literal) int x3 = 52_; // Invalid; cannot put underscores at the end of a literal int x4 = 5_______2; // OK (decimal literal) int x5 = 0_x52; // Invalid; cannot put underscores in the 0x radix prefix int x6 = 0x_52; // Invalid; cannot put underscores at the beginning of a number int x7 = 0x5_2; // OK (hexadecimal literal) int x8 = 0x52_; // Invalid; cannot put underscores at the end of a number int x9 = 0_52; // OK (octal literal) int x10 = 05_2; // OK (octal literal) int x11 = 052_; // Invalid; cannot put underscores at the end of a number
http://download.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html
Strings in switch Statements
switch文で文字列を
switch文の条件式でStringオブジェクトが使用できるようになりました。Javaコンパイラは一般的に、「if-then-else文よりもStringオブジェクトを用いるswitch文のほうが効率的なバイトコードを生成する。」とされています。
public String getTypeOfDayWithSwitchStatement(String dayOfWeekArg) { String typeOfDay; switch (dayOfWeekArg) { case "Monday": typeOfDay = "Start of work week"; break; case "Tuesday": case "Wednesday": case "Thursday": typeOfDay = "Midweek"; break; case "Friday": typeOfDay = "End of work week"; break; case "Saturday": case "Sunday": typeOfDay = "Weekend"; break; default: throw new IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg); } return typeOfDay; }
http://download.oracle.com/javase/7/docs/technotes/guides/language/strings-switch.html
Type Inference for Generic Instance Creation
ジェネリックインスタンス生成時の型推論
従来、このように記述していたものを
Map<String, List<String>> myMap = new HashMap<String, List<String>>();
このように記述することができるようになりました。
Map<String, List<String>> myMap = new HashMap<>();
「<>」を付与しないと警告が出力されますのでご注意ください。
Map<String, List<String>> myMap = new HashMap(); // unchecked conversion warning
http://download.oracle.com/javase/7/docs/technotes/guides/language/type-inference-generic-instance-creation.html
Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods
型パラメータを可変長引数で使用時のコンパイラ警告およびエラーの改善
ジェネリクスにより型の安全性が保証されているのにも関わらず、保証されていない型のオブジェクトが扱われてしまうようなケースが「ヒープ汚染」と呼ばれます。
List l = new ArrayList<Number>(); List<String> ls = l; // unchecked warning l.add(0, new Integer(42)); // another unchecked warning String s = ls.get(0); // ClassCastException is thrown
Java SE 7ではコンパイル時にヒープ汚染が起こる可能性がある場合、警告を出力するようになりました。
warning: [varargs] Possible heap pollution from parameterized vararg type T
この警告を出力しないようにするには、以下の方法があります。
- staticおよび非コンストラクタメソッドの宣言に次のアノテーションを追加します。
- @SafeVarargs
- メソッドの宣言に次のアノテーションを追加します。
- @SuppressWarnings({"unchecked", "varargs"})
- メソッド呼び出し側で生成される警告は抑制できません。
- コンパイラオプションに -Xlint:varargs を指定します。
http://download.oracle.com/javase/7/docs/technotes/guides/language/non-reifiable-varargs.html
The try-with-resources Statement
リソースを含めたtry文
プログラムが終了した際にクローズされていなければならないリソースをtry文に含めることができるようになりました。これらのリソースはステートメント終了時にクローズされることが保証されます。
static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } }
http://download.oracle.com/javase/7/docs/technotes/guides/language/try-with-resources.html
Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking
複数例外型キャッチと型チェックの改善による例外の再スロー
複数例外型をキャッチすることが可能となりました。このようなケースが
catch (IOException ex) { logger.log(ex); throw ex; catch (SQLException ex) { logger.log(ex); throw ex; }
このように記述できます。
catch (IOException|SQLException ex) { logger.log(ex); throw ex; }
キャッチした例外を再度スローする際、メソッド宣言のthrow節に、より特定の例外型を指定することができるようになりました。従来は、メソッド宣言のthrow節に「FirstException」と「SecondException」を指定することができませんでしたが(双方の親クラスである「Exception」を指定していた。)
static class FirstException extends Exception { } static class SecondException extends Exception { } public void rethrowException(String exceptionName) throws Exception { try { if (exceptionName.equals("First")) { throw new FirstException(); } else { throw new SecondException(); } } catch (Exception e) { throw e; } }
throw節に「FirstException」および「SecondeException」を指定することができます。
public void rethrowException(String exceptionName) throws FirstException, SecondException { try { // ... } catch (Exception e) { throw e; } }
http://download.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html
まとめ
Java SE 7では、言語拡張以外にも様々な改良が施されています。
http://download.oracle.com/javase/7/docs/
OracleによるSunの買収や、「Javaの父」ことジェームズ・ゴスリン氏のGoogle移籍など、Javaプラットフォームを取り巻く環境は大きく変化しましたが、「Scala」や「Groovy」などのJVM言語や心機一転したJavaFX 2.0など面白そうな話題もまだまだあるので、今後もチェックを続けていこうと思います。